package cn.yuemouren.security.app;

import cn.yuemouren.security.app.authentication.openid.OpenIdAuthenticationSecurityConfig;
import cn.yuemouren.security.core.authentication.mobile.SmsCodeAuthenticationSecurityConfig;
import cn.yuemouren.security.core.properties.OAuth2ClientProperties;
import cn.yuemouren.security.core.properties.OAuth2Properties;
import cn.yuemouren.security.core.properties.SecurityConstants;
import cn.yuemouren.security.core.properties.SecurityProperties;
import cn.yuemouren.security.core.validate.code.ValidateCodeSecurityConfig;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.builders.InMemoryClientDetailsServiceBuilder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
import org.springframework.social.security.SpringSocialConfigurer;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Timi
 * @Description: 认证服务器配置
 * @Date: 2020/7/1 21:34
 * @Version: v1.0
 */
@Configuration
@EnableAuthorizationServer
public class TimiAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private TokenStore tokenStore;

    @Autowired(required = false)
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired(required = false)
    private TokenEnhancer jwtTokenEnhancer;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore)
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);

        if(jwtTokenEnhancer != null && jwtAccessTokenConverter != null){
            TokenEnhancerChain chain = new TokenEnhancerChain();
            List<TokenEnhancer> params = new ArrayList<>();
            params.add(jwtAccessTokenConverter);
            params.add(jwtTokenEnhancer);
            chain.setTokenEnhancers(params);
            endpoints.tokenEnhancer(chain)
                    .accessTokenConverter(jwtAccessTokenConverter);
        }
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
        if(!ArrayUtils.isEmpty(securityProperties.getOauth2().getClient())){
            for (OAuth2ClientProperties properties : securityProperties.getOauth2().getClient()){
                builder.withClient(properties.getClientId())
                        .secret(properties.getClientSecret())
                        .accessTokenValiditySeconds(properties.getAccessTokenValiditySeconds())
                        .refreshTokenValiditySeconds(36000000)
                        //支持的grant类型
                        .authorizedGrantTypes("refresh_token", "authorization_code", "password")
                        //支持哪些权限
                        .scopes("all");
            }
        }
    }
}
